
// HDR Tone mapping.
// Pixel shader.
//------------------------------------------

// Defines.
//------------------------------------------
#define UCHAR_MAX 255
#define DELTA 0.0001

// Typedefs.
//------------------------------------------
struct Pixel
{
    float4 position : SV_POSITION;
	float2 uv       : TEXCOORD0;
};

// Globals.
//------------------------------------------
Texture2D g_frame;

SamplerState Sampler;

float4 Main(Pixel input) : SV_TARGET
{
	// Compute average luminance.
	float3 average_rgb = g_frame.SampleLevel(Sampler, float2(0, 0), UCHAR_MAX);
	float1 average_luminance = 0.27f * average_rgb.r + 0.67f * average_rgb.g + 0.06f * average_rgb.b;
	
	// Compute key.
	float1 log_average_luminance = exp(1.0f / log(DELTA + average_luminance));
	
	// Map to middle gray.
	// Valid values for a are : 0.045, 0.09, 0.18, 0.36, 0.72
	float1 a = 0.72f;
	
	float4 rgba = g_frame.SampleLevel(Sampler, input.uv, 0);
	float1 luminance = 0.27f * rgba.r + 0.67f * rgba.g + 0.06f * rgba.b;
	float1 scaled_luminance = a * luminance / log_average_luminance;
	
	// Compress high luminances.
	float1 tonemap_operator = scaled_luminance;
	
	if(scaled_luminance > 1)
		tonemap_operator = scaled_luminance / (1.0f + scaled_luminance);
	
	return float4(rgba.rgb * tonemap_operator,  1);
}